from PyQt4 import QtCore,QtGui
from pycute4 import PyCute


class Property:
	def __init__(self,name,getter,setter):
		self._name=name
		self._getter=getter
		self._setter=setter
		self._type=type(getter())
		self._designerValue=None
		
	def name(self):
		return self._name
	def type(self):
		return self._type

#	def set(self,*value):
#		self._setter(*value)
#		self._designerValue=value
	def set(self,*value):
		pass
	def canSetFromString(self):
		return self._type in [bool,int,float,QtCore.QString]
	def setFromString(self,value):
		if not self.canSetFromString():
			return False

		if self._type is bool:
			try:
				self._setter(bool(int(value)))
			except ValueError:
				self._setter(value.lower()=='true')
		elif self._type is int:
			try:
				self._setter(int(value))
			except ValueError:
				return False
		elif self._type is float:
			try: 
				self._setter(float(value))
			except ValueError:
				return False
		elif self._type is QtCore.QString:
			self._setter(value)
		
			
		return True

	def getAsString(self):
		value=self._getter()
		if self._type is QtCore.QSize:
			return '(%d,%d)' % (value.width(),value.height()) 
		elif self._type is QtCore.QString:
			return str(value)
		else:
			#This works for bool, int, float
			return repr(self._getter())
	def __repr__(self):
		return '%s=%s (%s)' %  (self._name,self._getter(),self._type)


class PropertyModel(QtCore.QAbstractTableModel):
	def __init__(self,properties=[],parent=None):
		QtCore.QAbstractListModel.__init__(self,parent)
		self._properties=properties
	def rowCount(self, parent=None):
		return len(self._properties)
	def columnCount(self,parent=None):
		return 3
	def data(self, index, role):
		property=self._properties[index.row()]
		if role == QtCore.Qt.DisplayRole: #show just the name
			if index.column()==0:
 				return property.name()
			elif index.column()==1:
				return property.getAsString()
			elif index.column()==2:
				return repr(property.type())

		elif role == QtCore.Qt.UserRole:  #return the whole python object
			return self._properties[index.row()]
		return QtCore.QVariant()
	def setData(self,index,value,role):
		if index.column()!=1:
			return False

		if role != QtCore.Qt.EditRole:
			return False
			
		property=self._properties[index.row()]
		return property.setFromString(str(value.toString()))
	def flags(self,index):
		if index.column()==1 and self._properties[index.row()].canSetFromString():
			return QtCore.QAbstractTableModel.flags(self,index) | QtCore.Qt.ItemIsEditable
		return QtCore.QAbstractTableModel.flags(self,index)

	def removeRow(self, position):
		pass


def getProperties(obj):
		#Build the property list
		properties=[]


		for attr in dir(obj):
			if attr=='setProperty':
				continue

			if attr.startswith('set'):
				setter=getattr(obj,attr)
				getterName=attr[3].lower()+attr[4:]
				if not hasattr(obj,getterName):
					continue
				getter=getattr(obj,getterName)

				properties.append(Property(attr[3:],getter,setter))
		return properties

	
if __name__=='__main__':
	app=QtGui.QApplication([])

	label=QtGui.QLineEdit() #QtGui.QLabel()
	label.setText('Hallo')
	label.show()

	model=PropertyModel(getProperties(label))
	listview=QtGui.QTableView()
	listview.setModel(model)
	listview.show()
	listview.resize(400,700)
	def focusChanged(old, now):
		if now is None:
			return
		x = now
		while x:
			if x is listview:
				return
			x = x.parentWidget()
		model=PropertyModel(getProperties(now))
		listview.setModel(model)

	print 'Ready'
	console=PyCute(app,locals={'app':app, 'label':label},fontSize=12)
	console.resize(400,300)
	console.setWindowTitle('Console')
	console.show()
	QtCore.QObject.connect(app, QtCore.SIGNAL("focusChanged(QWidget*,QWidget*)"), focusChanged)
	app.exec_()


